package com.rtx.edi.platform.tableconfig.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.rtx.api.utils.FastJsonUtils;
import com.rtx.api.utils.MultipleDataSource;
import com.rtx.common.EdiConstant;
import com.rtx.edi.db.service.DbService;
import com.rtx.edi.model.response.EdiResponse;
import com.rtx.edi.platform.ediapi.bean.EdiApi;
import com.rtx.edi.platform.ediapi.mapper.EdiApiMapper;
import com.rtx.edi.platform.ediapi.service.EdiApiService;
import com.rtx.edi.platform.tableconfig.bean.EdiColumnValueConfig;
import com.rtx.edi.platform.tableconfig.bean.EdiTableConfig;
import com.rtx.edi.platform.tableconfig.mapper.EdiColumnValueConfigMapper;
import com.rtx.edi.platform.tableconfig.mapper.EdiTableConfigMapper;
import com.rtx.edi.platform.tableconfig.service.EdiColumnValueConfigService;


@Service
public class EdiColumnValueConfigServiceImpl extends ServiceImpl<EdiColumnValueConfigMapper, EdiColumnValueConfig> implements EdiColumnValueConfigService{

	Logger logger = LoggerFactory.getLogger(this.getClass());
	
	@Autowired
	EdiTableConfigMapper ediTableConfigMapper;
	
	@Autowired
	EdiApiMapper ediApiMapper;
	
	@Autowired
	EdiApiService ediApiService;
	
	@Autowired
	DbService dbService;
	
	
	@Override
	public void selectList(Page<EdiColumnValueConfig> pageParam, EdiColumnValueConfig dto) {
		LambdaQueryWrapper<EdiColumnValueConfig> query = Wrappers.lambdaQuery();
		query.eq(EdiColumnValueConfig::getEditableconfigid, dto.getEditableconfigid());
		query.like(dto.getColumnname()!=null, EdiColumnValueConfig::getColumnname,dto.getColumnname());
		query.like(dto.getColumndescr()!=null, EdiColumnValueConfig::getColumndescr,dto.getColumndescr());
		query.like(dto.getConvertrule()!=null, EdiColumnValueConfig::getConvertrule,dto.getConvertrule());
//		query.like(dto.getIslinenumber()!=null, EdiColumnValueConfig::getIslinenumber,dto.getIslinenumber());
		query.like(dto.getIsseriakey()!=null, EdiColumnValueConfig::getIsseriakey,dto.getIsseriakey());
        baseMapper.selectPage(pageParam, query);
		
	}

	@Deprecated
	@Override
	public void initColumnsValueConfig(EdiColumnValueConfig dto) {
		LambdaQueryWrapper<EdiColumnValueConfig> query = Wrappers.lambdaQuery();
		query.eq(EdiColumnValueConfig::getEditableconfigid, dto.getEditableconfigid());
		boolean exists = baseMapper.exists(query);
		if(exists) {
			return;
		}
		EdiTableConfig configtable =	ediTableConfigMapper.selectById(dto.getEditableconfigid());
		EdiApi ediai  = ediApiMapper.selectById(configtable.getApiid());
		List<Map<String,String>> columns =	queryColumnsFromTable(ediai.getDatasource(),configtable.getName());
		
		for(Map<String,String> column:columns) {
			
			String columnname = column.get("Field").toLowerCase();
			String descr = column.get("Comment");
			EdiColumnValueConfig ediColumnValueConfig = new EdiColumnValueConfig();
			ediColumnValueConfig.setColumnname(columnname);
			ediColumnValueConfig.setColumndescr(descr);
			ediColumnValueConfig.setEditableconfigid(configtable.getId());
			
//			if(EdiConstant.EDI_API_TYPE_STD.equals(ediai.getType())) {
//				ediColumnValueConfig.setRequestvaluepath(subtable+"数组."+columnname);
//				subjson.put(columnname, descr);
//			}
			baseMapper.insert(ediColumnValueConfig);
		}
	}
	
	List<Map<String,String>> queryColumnsFromTable(String datasourcekey,String tablename){
		MultipleDataSource.setDataSourceKey(datasourcekey);
		String sql = "show full columns from "+tablename;
		List<Map<String, String>> list =  baseMapper.queryAllColumnsByTableName(sql);
		MultipleDataSource.ClearDataSourceKey();
		return list;
	}

	
	@Override
	public List<Map<String, String>> requestNodeSelect(EdiColumnValueConfig dto) {
		EdiTableConfig configtable =	ediTableConfigMapper.selectById(dto.getEditableconfigid());
		EdiApi ediai  = ediApiMapper.selectById(configtable.getApiid());
		String requestStr = ediai.getRequest();
		
		List<Map<String, String>> sSelectorList = new ArrayList<Map<String,String>>();
		
		List<Map<String, String>> tJsonList = FastJsonUtils.getFormatJSON(requestStr);
		
		for(Map<String,String> sJson:tJsonList) {
			if(!StringUtils.hasLength(sJson.get("fieldType"))) {
				Map<String,String> sSelector = new HashMap<String, String>();
				sSelector.put("label", sJson.get("fieldFullPath"));
				sSelector.put("value", sJson.get("fieldFullPath"));
				sSelectorList.add(sSelector);
			}
		}
		
		return sSelectorList;
	}
	
	@Override
	public EdiResponse deleteEdiColumnValueConfigByIds(List<EdiColumnValueConfig> list) {
		try {
			List<Long> ids = list.stream().map(p -> p.getId()).distinct().collect(Collectors.toList());
			this.removeBatchByIds(ids);

			Long tableconfigid = list.get(0).getEditableconfigid();
			EdiTableConfig configtable =	ediTableConfigMapper.selectById(tableconfigid);
			EdiApi ediai  = ediApiMapper.selectById(configtable.getApiid());
			if(EdiConstant.EDI_API_TYPE_STD.equals(ediai.getType())) {
				//重新生成报文
				String requestStr = ediApiService.buildStdRequestJson(ediai);
				LambdaUpdateWrapper<EdiApi> ediapiUpd = Wrappers.lambdaUpdate();
				ediapiUpd.set(EdiApi::getRequest, requestStr);
				ediapiUpd.eq(EdiApi::getId, ediai.getId());
				ediApiMapper.update(null, ediapiUpd);
			}
			return EdiResponse.success();
		} catch (Exception e) {
			logger.info("",e);
			return EdiResponse.failed().returnMgr(e.getMessage());
		}

	}
	
	@Override
	public EdiResponse editEdiColumnValueConfig(EdiColumnValueConfig dto) {
		try {
			EdiColumnValueConfig cvc = baseMapper.selectById(dto.getId());
			this.updateById(dto);
			EdiTableConfig configtable = ediTableConfigMapper.selectById(dto.getEditableconfigid());
			EdiApi ediai  = ediApiMapper.selectById(configtable.getApiid());
			
			String dtoActiverequest = Optional.ofNullable(cvc.getActiverequest()).orElse("");
			//是否为报文节点有改动
			if(EdiConstant.EDI_API_TYPE_STD.equals(ediai.getType()) && (!dtoActiverequest.equals(dto.getActiverequest()))) {
				//重新生成报文
				String requestStr = ediApiService.buildStdRequestJson(ediai);
				LambdaUpdateWrapper<EdiApi> ediapiUpd = Wrappers.lambdaUpdate();
				ediapiUpd.set(EdiApi::getRequest, requestStr);
				ediapiUpd.eq(EdiApi::getId, ediai.getId());
				ediApiMapper.update(null, ediapiUpd);
			}
			return EdiResponse.success();
		} catch (Exception e) {
			logger.info("",e);
			return EdiResponse.failed().returnMgr(e.getMessage());
		}
	}
	
	

	@Override
	public EdiResponse addEdiColumnValueConfig(EdiColumnValueConfig dto) {
		try {
			dto.setEdinewcolumnflag("true");
			
			this.save(dto);
			
			EdiTableConfig configtable = ediTableConfigMapper.selectById(dto.getEditableconfigid());
			EdiApi ediai  = ediApiMapper.selectById(configtable.getApiid());
			//是否为报文节点有改动
			if(EdiConstant.EDI_API_TYPE_STD.equals(ediai.getType()) && "true".equals(dto.getActiverequest())) {
				//重新生成报文
				String requestStr = ediApiService.buildStdRequestJson(ediai);
				LambdaUpdateWrapper<EdiApi> ediapiUpd = Wrappers.lambdaUpdate();
				ediapiUpd.set(EdiApi::getRequest, requestStr);
				ediapiUpd.eq(EdiApi::getId, ediai.getId());
				ediApiMapper.update(null, ediapiUpd);
			}
			return EdiResponse.success();
		} catch (Exception e) {
			logger.info("",e);
			return EdiResponse.failed().returnMgr(e.getMessage());
		}
	}

	@Override
	public EdiResponse queryCurrentConfig(EdiColumnValueConfig dto) {
		Map<String,Object> map = new HashMap<>();
		MultipleDataSource.setDataSourceKey("ris_edi");
		
		try {
			//数据库中所有字段
			EdiTableConfig configtable =	ediTableConfigMapper.selectById(dto.getEditableconfigid());
			EdiApi ediai  = ediApiMapper.selectById(configtable.getApiid());
			List<Map<String,String>> columns =	queryColumnsFromTable(ediai.getDatasource(),configtable.getName());
			List<EdiColumnValueConfig> allColumn = new ArrayList<EdiColumnValueConfig>();
			for(Map<String,String> column:columns) {
				String columnname = column.get("Field").toLowerCase();
				String type = column.get("Type").toLowerCase();
				String descr = column.get("Comment");
				EdiColumnValueConfig ediColumnValueConfig = new EdiColumnValueConfig();
				ediColumnValueConfig.setColumnname(columnname);
				ediColumnValueConfig.setColumndescr(descr);
				ediColumnValueConfig.setEditableconfigid(configtable.getId());
				if(type.contains("datetime")) {
					ediColumnValueConfig.setValuetype("date");
				}
				allColumn.add(ediColumnValueConfig);
			}
			
			map.put("allcolumn", allColumn);
			
			//当前生效字段
			LambdaQueryWrapper<EdiColumnValueConfig> qw = Wrappers.lambdaQuery();
			qw.eq(EdiColumnValueConfig::getEditableconfigid, dto.getEditableconfigid());
			List<EdiColumnValueConfig> currentColumnData = Optional.ofNullable(baseMapper.selectList(qw)).orElse(new ArrayList<>());
			List<String> currentColumn = currentColumnData.stream().map(temp->temp.getColumnname()).collect(Collectors.toList()); 
			map.put("currentcolumn", currentColumn);
			
			return EdiResponse.success().data("map", map);
		} catch (Exception e) {
			MultipleDataSource.setDataSourceKey("ris_edi");
			logger.info("",e);
			return EdiResponse.failed().returnMgr(e.getMessage());
		}
		
	}

	@Override
	public EdiResponse saveCurrentConfig(String requestStr) {
		try {
			JSONObject requesJSON = JSON.parseObject(requestStr);
			//获取前端传过来表配置id
			String editableconfigid = requesJSON.getString("editableconfigid");
			//配置需要生效的字段列表
			List<String> configList = requesJSON.getJSONArray("currentcolumn").toJavaList(String.class);
			
			//获取表配置
			EdiTableConfig ediTableConfig = ediTableConfigMapper.selectById(editableconfigid);
			String tablename = ediTableConfig.getName();
			Long apiid = ediTableConfig.getApiid();
			
			//获取api配置信息
			EdiApi ediApi =	ediApiService.getBaseMapper().selectById(apiid);
			String datasourcekey = ediApi.getDatasource();
			
			//获取已经存在的字段配置信息
			LambdaQueryWrapper<EdiColumnValueConfig> qw = Wrappers.lambdaQuery();
			qw.eq(EdiColumnValueConfig::getEditableconfigid, editableconfigid);
			List<EdiColumnValueConfig> currentColumnList = Optional.ofNullable(baseMapper.selectList(qw)).orElse(new ArrayList<>());
			List<String> dbColumn = currentColumnList.stream().map(temp->temp.getColumnname()).collect(Collectors.toList());
			
			//所有字段
			List<String> allList = new ArrayList<>();
			allList.addAll(configList);
			allList.addAll(dbColumn);
			List<String> allcolumns =allList.stream().distinct().collect(Collectors.toList());
			
			for(String column:allcolumns) {
				if(!dbColumn.contains(column) && configList.contains(column)) {
					//数据库不存在 新的配置列表中存在 则新增
					EdiColumnValueConfig cvc = new EdiColumnValueConfig();
					cvc.setColumnname(column);
					cvc.setActiverequest("true");
					cvc.setEditableconfigid(Long.parseLong(editableconfigid));
					
					String type = dbService.queryTableFieldType(datasourcekey, tablename, column);
					if(type.contains("datetime")) {
						cvc.setValuetype("Date");
					}
					
					baseMapper.insert(cvc);
				}else if(dbColumn.contains(column) && !configList.contains(column)) {
			       Optional<EdiColumnValueConfig> todelConfig =	currentColumnList.stream().filter(temp->column.equals(temp.getColumnname())).findFirst();
			       if(!todelConfig.isPresent()) {
			    	   continue;
			       }
			       if("true".equals(todelConfig.get().getEdinewcolumnflag())) {
			    	   continue;
			       }
			       baseMapper.deleteById(todelConfig.get().getId());
				}
			}
			
			EdiTableConfig configtable =	ediTableConfigMapper.selectById(editableconfigid);
			EdiApi ediai  = ediApiMapper.selectById(configtable.getApiid());
			if(EdiConstant.EDI_API_TYPE_STD.equals(ediai.getType())) {
				//重新生成报文
				String buildRequest = ediApiService.buildStdRequestJson(ediai);
				LambdaUpdateWrapper<EdiApi> ediapiUpd = Wrappers.lambdaUpdate();
				ediapiUpd.set(EdiApi::getRequest, buildRequest);
				ediapiUpd.eq(EdiApi::getId, ediai.getId());
				ediApiMapper.update(null, ediapiUpd);
			}
			
			return EdiResponse.success();
		} catch (Exception e) {
			logger.info("",e);
			return EdiResponse.failed().returnMgr(e.getMessage());
		}
	}
}
